/**
 * @file SwTask.h
 * @brief 
 * 
 * swTask —— switch task
 * 受到ProtoTheard和nodejs promise的启发，
 * 简单封装了switch的操作，使得异步协程的实现更加简洁
 * 
 * 具体文档见 https://gitee.com/zyanishere/sw-task
 * 
 * @author Zyan (zyishere2001@qq.com)
 * @version 1.1
 * @date 2022-12-21
 * 
 * @copyright Copyright (c) 2022  Zyanishere2001
 * 
 * @par 修改日志:
 * 2022-12-21 ver1.0 : 基础功能，入口，出口，等待，定时等
 * 2022-12-22 ver1.1 : 添加错误处理能力
 * 2022-12-22 ver1.2 : 分离错误处理能力
 */


#pragma once

/**
 * ================= 类型/常值 =================
 */
typedef unsigned short sw_task_t;   //任务类型
typedef unsigned short sw_tim_t;    //定时器装载值
//返回值
#define SW_WAITING      0   //任务正在运行
#define SW_ENDED        3   //任务已经完成
//basic
#define SW_INIT(s)  s = 0;  //初始化状态
#define SW_SET(s)   s = __LINE__; case __LINE__:    //设定状态断点入口


/**
 * ================= 基本入口/出口 =================
 */

//总入口，封装switch
#define SW_BEGIN(s)                             \
                        switch (s) {            \
                            case 0:   
//总出口，封装switch尾
#define SW_END(s)       }                       \
                        SW_INIT(s);             \
                        return SW_ENDED;        \



/**
 * =============== 事件/任务 ===============
*/
//异步等待事件
#define SW_WAIT_UNTIL(s, condition)     \
    do{                                 \
        SW_SET(s);                      \
        if(!(condition)) {				\
            return SW_WAITING;			\
        }	                            \
    }while(0)


//异步等待任务
#define SW_WAIT_TASK(s, task)     SW_WAIT_UNTIL(s, task != SW_WAITING)


/**
 * =============== 延时 ===============
 * 也是让出执行权
*/

//异步延时
#define SW_DELAY(s, t, l)                       \
    do{                                         \
        t = l;                                  \
                                                \
        SW_SET(s);                              \
        t--;                                    \
        if(t != 0) {				            \
            return SW_WAITING;			        \
        }                                       \
    }while (0)

